﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;

namespace CoreLibrary
{
    public static class Extensions
    {
        #region 字符串扩展方法

        /// <summary>
        /// 转全角(SBC case)
        /// </summary>
        /// <param name="input">任意字符串</param>
        /// <returns>全角字符串</returns>
        public static string ToSBC(this string input)
        {
            char[] c = input.ToCharArray();
            for (int i = 0; i < c.Length; i++)
            {
                if (c[i] == 32)
                {
                    c[i] = (char)12288;
                    continue;
                }
                if (c[i] < 127)
                {
                    c[i] = (char)(c[i] + 65248);
                }
            }
            return new string(c);
        }

        /// <summary>
        /// 转半角(DBC case)
        /// </summary>
        /// <param name="input">任意字符串</param>
        /// <returns>半角字符串</returns>
        public static string ToDBC(this string input)
        {
            char[] c = input.ToCharArray();
            for (int i = 0; i < c.Length; i++)
            {
                if (c[i] == 12288)
                {
                    c[i] = (char)32;
                    continue;
                }
                if (c[i] > 65280 && c[i] < 65375)
                {
                    c[i] = (char)(c[i] - 65248);
                }
            }
            return new string(c);
        }

        /// <summary>
        /// 判断是否为空
        /// </summary>
        /// <param name="input">任意字符串</param>
        /// <returns></returns>
        public static bool IsEmpty(this string input)
        {
            return String.IsNullOrEmpty(input);
        }

        /// <summary>
        /// 判断是否为整型
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static bool IsInt(this string s)
        {
            int i;
            return Int32.TryParse(s, out i);
        }

        /// <summary>
        /// 转换成整型
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static int ToInt(this string s)
        {
            return Convert.ToInt32(s);
        }

        #endregion

        #region 字节扩展方法

        /// <summary>
        /// 转换为十六进制字符串
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        public static string ToHex(this byte b)
        {
            return b.ToString("X2");
        }

        /// <summary>
        /// 转换为十六进制字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string ToHex(this IEnumerable<byte> bytes)
        {
            StringBuilder sb = new StringBuilder();
            foreach (byte b in bytes)
            {
                sb.Append(b.ToString("X2"));
            }
            return sb.ToString();
        }

        /// <summary>
        /// 转换为Base64字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string ToBase64String(this byte[] bytes)
        {
            return Convert.ToBase64String(bytes);
        }

        /// <summary>
        /// 转换成int型
        /// </summary>
        /// <param name="value"></param>
        /// <param name="startIndex"></param>
        /// <returns></returns>
        public static int ToInt(this byte[] value, int startIndex)
        {
            return BitConverter.ToInt32(value, startIndex);
        }

        /// <summary>
        /// 转换成long型
        /// </summary>
        /// <param name="value"></param>
        /// <param name="startIndex"></param>
        /// <returns></returns>
        public static long ToInt64(this byte[] value, int startIndex)
        {
            return BitConverter.ToInt64(value, startIndex);
        }

        /// <summary>
        /// //使用指定算法Hash
        /// </summary>
        /// <param name="data"></param>
        /// <param name="hashName"></param>
        /// <returns></returns>
        public static byte[] Hash(this byte[] data, string hashName)
        {
            HashAlgorithm algorithm;
            if (String.IsNullOrEmpty(hashName)) algorithm = HashAlgorithm.Create();
            else algorithm = HashAlgorithm.Create(hashName);
            return algorithm.ComputeHash(data);
        }

        /// <summary>
        /// 使用默认算法Hash
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] Hash(this byte[] data)
        {
            return Hash(data, null);
        }

        /// <summary>
        /// 保存为文件 
        /// </summary>
        /// <param name="data"></param>
        /// <param name="path"></param>
        public static void Save(this byte[] data, string path)
        {
            File.WriteAllBytes(path, data);
        }

        /// <summary>
        /// 转换为内存流 
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static MemoryStream ToMemoryStream(this byte[] data)
        {
            return new MemoryStream(data);
        }

        #endregion

        #region 实体扩展方法

        /// <summary>
        /// DataRow转成实体
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="row">DataRow</param>
        /// <returns>实体</returns>
        public static T ToEntity<T>(this DataRow row)
            where T : new()
        {
            T t = new T();
            //获得实体类型所有公共属性
            List<PropertyInfo> properties = typeof(T).GetProperties().ToList();

            //获得DataRow所有列名
            row.Table.Columns.Cast<DataColumn>().Select(p => p.ColumnName).ToList()
                .ForEach(p =>
                             {
                                 //查找与列名相同的属性
                                 try
                                 {
                                     PropertyInfo property = properties.Single(s => s.Name.ToLower().Equals(p.ToLower()));
                                     if (row[p] != null)
                                     {
                                         try
                                         {
                                             Type type = property.PropertyType;
                                             //转化类型后赋值
                                             if (type == typeof(int?))
                                                 type = typeof(System.Int32);
                                             else if (type == typeof(DateTime?))
                                                 type = typeof(System.DateTime);
                                             else if (type == typeof(decimal?))
                                                 type = typeof(System.Decimal);
                                             property.SetValue(t, Convert.ChangeType(row[p], type), null);
                                         }
                                         catch (Exception ex)
                                         {
                                             throw ex;
                                         }
                                     }
                                 }
                                 catch (Exception ex)
                                 {
                                     throw ex;
                                 }
                             });
            return t;
        }

        /// <summary>
        /// DataTable转实体列表
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="dt">DataTable</param>
        /// <returns>实体列表</returns>
        public static List<T> ToEntityList<T>(this DataTable dt)
            where T : new()
        {
            List<T> list = new List<T>();
            //获得DataTable中所有DataRow
            foreach (DataRow row in dt.Rows)
            {
                T model = row.ToEntity<T>();
                list.Add(model);
            }
            return list;
        }

        #endregion
    }
}
